use std::fs;

use crate::datetime::DateTime;

const ICON_UP: &str = "";
const ICON_DOWN: &str = "";
const INTERFACE: &str = "wlp1s0";
const NET_INFO_FILE: &str = "/proc/net/dev";

pub struct NetInfo {
    tx_prev: u64,
    rx_prev: u64,
    ts_prev: u64,
    tx_next: u64,
    rx_next: u64,
    ts_next: u64,
}

impl NetInfo {
    pub fn new() -> Self {
        NetInfo {
            tx_prev: 0,
            rx_prev: 0,
            ts_prev: 0,
            tx_next: 0,
            rx_next: 0,
            ts_next: 0,
        }
    }

    pub fn display(&mut self) -> String {
        if self.update() {
            let ts_diff = self.ts_next - self.ts_prev;
            let rx_diff = self.rx_next - self.rx_prev;
            let tx_diff = self.tx_next - self.tx_prev;
            // println!("diff {} {}", tx_diff, rx_diff);
            let rx_rate = (1000 * rx_diff / ts_diff) as f64 / 1024.0;
            let tx_rate = (1000 * tx_diff / ts_diff) as f64 / 1024.0;
            let tx_str = if tx_rate > 1024.0 {
                format!("{:.2}MB/s", (tx_rate / 1024.0))
            } else {
                format!("{:.0}KB/s", tx_rate)
            };
            let rx_str = if rx_rate > 1024.0 {
                format!("{:.2}MB/s", (rx_rate / 1024.0))
            } else {
                format!("{:.0}KB/s", rx_rate)
            };
            format!("{} {} {} {}", ICON_UP, tx_str, ICON_DOWN, rx_str)
        } else {
            String::new()
        }
    }

    /// rx, tx
    fn update(&mut self) -> bool {
        if let Ok(content) = fs::read_to_string(NET_INFO_FILE) {
            if let Some(start_index) = content.find(INTERFACE) {
                let a = &content[start_index..];
                if let Some(end_index) = a.find('\n') {
                    let b = &a[..end_index];
                    let list: Vec<&str> = b.split(' ').filter(|x| *x != "").collect();
                    if list.len() == 17 {
                        // println!("{} {}", list[1], list[9]);
                        if let Ok(rx) = list[1].parse::<u64>() {
                            if let Ok(tx) = list[9].parse::<u64>() {
                                self.rx_prev = self.rx_next;
                                self.tx_prev = self.tx_next;
                                self.ts_prev = self.ts_next;
                                self.rx_next = rx;
                                self.tx_next = tx;
                                self.ts_next = DateTime::timestamp();
                                return true;
                            }
                        }
                    }
                }
            }
        }
        false
    }
}
